﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using NUnit.Framework;
using Obra.Common;
using Obra.SmugMug.Api;

namespace Obra.Test
{
    /// <summary>
    /// Validate HTTP upload requests are correct.
    /// </summary>
    internal class SmugMugUploadRequestValidate
        : IHttpRequestValidate
    {
        public HttpListenerRequest Request
        {
            get;
            set;
        }

        public ulong ExpectedLength
        {
            get;
            set;
        }

        public string ExpectedChecksum
        {
            get;
            set;
        }

        public string ExpectedSessionId
        {
            get;
            set;
        }

        public string ExpectedVersion
        {
            get;
            set;
        }

        public string ExpectedAlbumId
        {
            get;
            set;
        }

        public string ExpectedImageId
        {
            get;
            set;
        }

        public string ExpectedFileName
        {
            get;
            set;
        }

        public string ExpectedResponseType
        {
            get;
            set;
        }

        public void ValidateHeaderLength()
        {
            UInt64 length = UInt64.Parse(this.Request.Headers.Get("Content-Length"));
            Assert.AreEqual(this.ExpectedLength, this.Request.ContentLength64);
            Assert.AreEqual(this.ExpectedLength, length);
        }

        public void ValidateContentChecksum()
        {
            string computedChecksum = new Checksum(
                this.Request.InputStream).ToString();
            Assert.AreEqual(this.ExpectedChecksum, this.Request.Headers.Get("Content-MD5"));
            Assert.AreEqual(this.ExpectedChecksum, computedChecksum);
        }

        public void ValidateSmugSessionId()
        {
            Assert.AreEqual(this.ExpectedSessionId, this.Request.Headers.Get("X-Smug-SessionID"));
        }

        public void ValidateSmugVersion()
        {
            Assert.AreEqual(this.ExpectedVersion, this.Request.Headers.Get("X-Smug-Version"));
        }

        public void ValidateAlbumId()
        {
            Assert.AreEqual(this.ExpectedAlbumId, this.Request.Headers.Get("X-Smug-AlbumID"));
        }

        public void ValidateImageId()
        {
            Assert.AreEqual(this.ExpectedImageId, this.Request.Headers.Get("X-Smug-ImageID"));
        }

        public void ValidateSmugFileName()
        {
            Assert.AreEqual(this.ExpectedFileName, this.Request.Headers.Get("X-Smug-FileName"));

            string uriString = String.Format("/{0}", this.ExpectedFileName);
            Assert.IsTrue(this.Request.Url.OriginalString.EndsWith(uriString));
        }

        public void ValidateSmugResponeType()
        {
            Assert.AreEqual(this.ExpectedResponseType, this.Request.Headers.Get("X-Smug-ResponseType"));
        }

        #region IHttpRequestValidate Members

        public void Validate(HttpListenerRequest request)
        {
            this.Request = request;
            
            Assert.IsTrue(
                this.Request.HasEntityBody);
            
            Assert.AreEqual(
                UploadServiceProvider.DefaultUploadHttpMethod,
                this.Request.HttpMethod);

            this.ValidateHeaderLength();
            this.ValidateContentChecksum();
            this.ValidateSmugSessionId();
            this.ValidateSmugVersion();
            this.ValidateAlbumId();
            this.ValidateImageId();
            this.ValidateSmugFileName();
            this.ValidateSmugResponeType();
        }

        #endregion
    }
}
